package com.googlecode.ddplan.dwr.domain;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import com.googlecode.ddplan.PDDLName;
import com.googlecode.ddplan.PDDLState;
import com.googlecode.ddplan.PDDLType;


@PDDLType
public class Location {
	public enum Type {
		NORTH, SOUTH, EAST, WEST;
	}
	
	@PDDLName
	private String name;

	private Map<Location.Type, Location> adiacentLocations;
	private Set<Pile> piles;
	private Crane crane;
	private Robot robot;

	public Location(String name, Map<Location.Type, Location> adiacentLocations) {
		this(name);
		this.adiacentLocations = adiacentLocations;
	}

	public Location(String name) {
		this.name = name;
		piles = new HashSet<Pile>();
	}

	public void addCrane(Crane crane) {
		if (this.crane != null) {
			throw new IllegalStateException("Crane already built!");
		}
		this.crane = crane;
	}

	public Pile getPileByNumber(int number) {
		for (Pile pile : piles) {
			if (pile.getNumber() == number) {
				return pile;
			}
		}
		return null;
	}

	public void attachPile(Pile pile) {
		if (getPileByNumber(pile.getNumber()) != null) {
			throw new IllegalArgumentException(
					"Pallet number already assigned for this location");
		}
		piles.add(pile);
	}

	public void enterRobot(Robot robot) {
		this.robot = robot;
	}

	public void freeRobot() {
		this.robot = null;
	}

	public boolean hasCrane(Crane crane) {
		return this.crane.equals(crane);
	}

	public boolean hasPile(Pile pallet) {
		return piles.contains(pallet);
	}

	public boolean hasRobot(Robot robot) {
		if (!occupied()) {
			return false;
		}
		return this.robot.equals(robot);
	}

	@PDDLState
	public boolean adjacent(Location location) {
		return adiacentLocations.containsValue(location);
	}

	@PDDLState
	public boolean occupied() {
		return robot != null;
	}

}
